home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Extra 1997 #1 / Amiga Plus Extra 1997 #1.iso / programme / tools / leoutils / leoclock.a < prev    next >
Text File  |  1996-03-26  |  8KB  |  319 lines

  1. ;    .          _               .   .  .
  2. ;    |   _  _  / \|  _  _ |    /|  /| /|
  3. ;    |  |_)/ \(   | / \| `|/    |   |  |
  4. ;    |__|_,\_/ \_/|_\_/|_,|\    |o  |  |
  5. ;
  6. ;    1993-04-27
  7. ;    1993-06-28
  8. ;    1995-02-09
  9. ;    1996-03-26
  10. ;
  11. ;
  12. ;    Here it is, the complete OS 2.0 clock that fits in one (1) FFS
  13. ;    disk block; less than 512 bytes, that is.
  14. ;
  15. ;    If you get this any smaller, or just want to write something
  16. ;    to me, please mail me to the following addresses:
  17. ;
  18. ;    Henrik Herranen
  19. ;    Atomikatu 6 A 9
  20. ;    SF-33720 Tampere
  21. ;    Finland
  22. ;
  23. ;    e-mail: leopold@cs.tut.fi
  24. ;
  25. ;    New for v1.01: The clock now fits on 1 OFS disk block (488 bytes)!
  26. ;    New for v1.10: With help from jhsa@cs.tut.fi and albert@cs.tut.fi 36
  27. ;        bytes saved (JUST LOOK AT THE OPENING OF LIBRARIES!) :-) .
  28. ;    New for v1.11: With help from Timo Kaikumaa (timok@cs.tut.fi) another
  29. ;        12 bytes went away. 440 to go.
  30.  
  31.  
  32. ;    The following lines would normally be included from external files
  33.  
  34. ;    include 'ainclude:macros.i'
  35. ;    include 'ainclude:include.i'
  36.  
  37. _LVOOpenLibrary        EQU    -552
  38. _LVOChangeWindowBox    EQU    -486
  39. _LVOCloseLibrary    EQU    -414
  40. _LVOOldOpenLibrary    EQU    -408
  41. _LVOReplyMsg        EQU    -378
  42. _LVOGetMsg        EQU    -372
  43. _LVOWindowToFront    EQU    -312
  44. _LVOSetTaskPri        EQU    -300
  45. _LVOFindTask        EQU    -294
  46. _LVOSizeWindow        EQU    -288
  47. _LVOSetWindowTitles    EQU    -276
  48. _LVOOpenWindow        EQU    -204
  49. _LVODelay        EQU    -198
  50. _LVODateStamp        EQU    -192
  51. _LVOMoveWindow        EQU    -168
  52. _LVOCloseWindow        EQU    -72
  53. _LVOTextLength        EQU    -54
  54.  
  55. WBENCHSCREEN    EQU    1
  56.  
  57. wd_WScreen    EQU    $2E
  58. wd_UserPort    EQU    $56
  59. wd_LeftEdge    EQU    $4
  60. wd_TopEdge    EQU    $6
  61. sc_Width    EQU    $C
  62. sc_BarHeight    EQU    $1E
  63. sc_RastPort    EQU    $54
  64. lib_Revision    EQU    $16
  65.  
  66. IDCMP_CLOSEWINDOW    equ    $200
  67. WFLG_CLOSEGADGET    equ    $8
  68. WFLG_DEPTHGADGET    equ    $4
  69. WFLG_DRAGBAR        equ    $2
  70.  
  71. ;
  72. ;    Here begins my code
  73. ;
  74. WIDEST        equr    d4
  75. CURRWIDTH    equr    d2
  76. WIN        equr    a3
  77.  
  78. INTUITIONBASE    equr    d5
  79. EXECBASE    equr    d6
  80. GRAPHICSBASE    equr    a4
  81.  
  82. ASC0        equr    d3
  83. LAST_MINUTE    equr    d7
  84.  
  85.                 ; The registers A2 and A5 are left for free use
  86.     section text,CODE
  87.  
  88. main:
  89. ;    OpenLib    dos
  90.  
  91.     moveq.l    #60-60,WIDEST
  92. ;    moveq.l    #-1,LAST_MINUTE        ; Not necessarily needed
  93.  
  94.     move.l    $4.w,EXECBASE        ; My version of A68k doesn't like the
  95.                     ; .w extension. Take it away if it
  96.                     ; disturbs your compiler.
  97.  
  98.     move.l    EXECBASE,a6
  99.  
  100.     sub.l    a1,a1            ; MyTask = FindTask(0);
  101.     jsr    _LVOFindTask(a6)
  102.     move.l    d0,-(sp)        ; Store MyTask to stack
  103.  
  104.     move.l    d0,a1            ; InheritedPri = SetTaskPri(MyTask, 4);
  105.     moveq.l    #4,d0
  106.     jsr    _LVOSetTaskPri(a6)
  107.     move.w    d0,-(sp)        ; Store InheritedPri to stack
  108.  
  109.     lea    IntuitionName(pc),a1    ; IntuitionBase = OldOpenLibrary("intuition.library");
  110.     lea    _LVOOldOpenLibrary(a6),a5
  111.     jsr    (a5)
  112.     move.l    d0,INTUITIONBASE
  113.  
  114.     lea    IntuitionName+7(pc),a1    ; DosBase = OldOpenLibrary("dos.library");
  115.     addq.w    #'os'-'on',(a1)
  116.     subq.b    #'i'-'d',-(a1)
  117.     jsr    (a5)
  118.     move.l    d0,-(sp)
  119.  
  120.     lea    IntuitionName+9(pc),a1
  121.     lea    Gfx+8(pc),WIN
  122.     move.l    -(WIN),-(a1)        ; GraphicsBase = OldOpenLibrary("graphics.library");
  123.     move.l    -(WIN),-(a1)
  124.     jsr    (a5)
  125.     move.l    d0,GRAPHICSBASE
  126.  
  127.     move.l    INTUITIONBASE,a6    ; Win = OpenWindow(&NewWin);
  128.     lea    NewWin(pc),a0
  129.     jsr    _LVOOpenWindow(a6)
  130.     move.l    d0,WIN            ; if (!Win) exit(0);
  131.     tst.l    d0
  132.     beq    FailedOpeningWindow
  133.  
  134. MainLoop:
  135.     move.l    (sp),a6            ; DateStamp(&MyDate); (DosBase is on top of the stack)
  136.     lea    MyDate(pc),a2
  137.     move.l    a2,d1
  138.     jsr    _LVODateStamp(a6)
  139.  
  140. ;    lea    MyDate_Minute(pc),a2    ; if (MyDate_Minute != LastMinute)
  141.     addq.l    #MyDate_Minute-MyDate,a2
  142.     cmp.l    (a2),LAST_MINUTE
  143.     beq.s    MinuteNotChanged
  144.  
  145.     move.l    INTUITIONBASE,a6    ;     WindowToFront(Win);
  146.     move.l    WIN,a0
  147.     jsr    _LVOWindowToFront(a6)
  148.  
  149. MinuteNotChanged:
  150.     moveq.l    #'0',ASC0        ; Here ASC0 gets its nominal value '0'
  151.  
  152.     move.l    (a2)+,LAST_MINUTE    ; LastMinute = MyDate_Minute;
  153.     move.l    wd_WScreen(WIN),a5    ; a5 = Win -> WScreen
  154.  
  155.     lea    TimeStr(pc),a1        ; TimeStr[0] = MyDate_Minute / 600 + '0';
  156.     move.l    LAST_MINUTE,d0
  157.     divu.w    #600,d0
  158.     bne.s    1$
  159.     subq.l    #1,a1
  160. 1$:    bsr.s    setnum
  161.  
  162.     moveq.l    #60,d1            ; TimeStr[1] = MyDate_Minute / 60 + '0';
  163.     bsr.s    divud1d0_setnum
  164.  
  165.     moveq.l    #10,d1            ; TimeStr[3] = MyDate_Minute / 10 + '0';
  166.     bsr.s    adda1_divud1d0_setnum
  167.  
  168.     bsr.s    setnum            ; TimeStr[4] = MyDate_Minute + '0';
  169.  
  170.     move.l    (a2)+,d0        ; TimeStr[6] = MyDate_Tick / 50 / 10 + '0';
  171.     divu.w    #50,d0
  172.     move.l    d0,-(sp)        ; Store whole 32-bit division result for later use
  173.     ext.l    d0
  174.  
  175.     bsr.s    adda1_divud1d0_setnum
  176.     bsr.s    setnum            ; TimeStr[7] = MyDate_Tick / 50 + '0';
  177.     bra.s    aftersetnum
  178.  
  179. ; The structures have moved here for easier access. Parts of the NewWindow
  180. ; structure has been changed to contain code.
  181.     
  182. MyDate:
  183. MyDate_Days:
  184. Gfx:    dc.b    "grap"
  185. MyDate_Minute:
  186.     dc.b    "hics"
  187. MyDate_Tick:
  188. Pad:    dc.b    0
  189.  
  190. IntuitionName:
  191.     dc.b    "intu"
  192. TimeStr:
  193.     dc.b    "ition.library"
  194. NewWin:
  195.     dc.w    0,0,60,20        ; Left, Top, Width, Height
  196.     dc.b    1,2            ; DetailPen, BlockPen
  197.     dc.l    IDCMP_CLOSEWINDOW    ; IDCMP flags
  198.     dc.l    WFLG_CLOSEGADGET+WFLG_DEPTHGADGET+WFLG_DRAGBAR    ; Flags
  199.     dc.l    0            ; *FirstGadget
  200.     dc.l    0            ; *CheckMark
  201.     dc.l    0            ; *WindowTitle
  202.  
  203. ; Changing the length of this code will kill the compiler. The correct length
  204. ; is 16 bytes (move.b is 4 bytes, other commands 2 bytes/cmd)
  205.  
  206. adda1_divud1d0_setnum:            ; *Screen, *BitMap, Min/Max-Width/Height
  207.     move.b    #':',(a1)+
  208. divud1d0_setnum:
  209.     divu.w    d1,d0
  210. setnum:
  211.     or.b    ASC0,d0            ; This is "or" and not "add" because "or" might be faster :-)
  212.     move.b    d0,(a1)+
  213.     swap    d0            ; These were the most common commands after calling setnum!
  214.     ext.l    d0            ;   The code is not always needed, but doesn't do any harm either,
  215.                     ;   and again another 8 bytes was saved!
  216.     rts
  217. ; End of code inserted to NewWindow structure
  218.  
  219. WantedLoc:
  220.     dc.w    WBENCHSCREEN        ; Type of mother screen
  221.  
  222. ; End of NewWindow structure
  223.  
  224. aftersetnum:
  225.     clr.b    (a1)            ; NULL terminate string
  226.     move.l    INTUITIONBASE,a6    ; SetWindowTitles(Win, &TimeStr[0 (or 1)], (UBYTE *) ~0L);
  227.     move.l    WIN,a0
  228.  
  229.                     ; Now a2 points to the next longword after MyDate_Tick
  230.                     ; Thus, by adding 1 you can get the address of TimeStr!
  231.     addq.l    #TimeStr-MyDate_Tick-4,a2
  232.     exg    a1,a2
  233.     move.l    a1,ASC0            ; ASC0 looses its value '0' here!!!
  234.     sub.l    a1,a2            ; a2 = length of string
  235. ;    Display "LEN=",long,a2
  236. ;    Display "PTR=",long,a1
  237.     move.l    a2,-(sp)        ; put length to stack
  238.     move.w    #-1,a2            ; no ScreenTitle string
  239.     jsr    _LVOSetWindowTitles(a6)
  240.  
  241.     lea    sc_RastPort(a5),a1    ; CurrWidth = TextLength(Win->WScreen.RastPort, TimeStr[0/1], 8/7);
  242.  
  243.     move.l    ASC0,a0            ; ASC0 isn't '0' anymore
  244.     move.l    (sp)+,d0
  245.  
  246.     move.l    GRAPHICSBASE,a6
  247.     jsr    _LVOTextLength(a6)
  248.     move.w    d0,CURRWIDTH
  249.  
  250.     cmp.w    WIDEST,CURRWIDTH    ; if (CurrWidth > Widest) {
  251.     ble.s    EndUpdate
  252.  
  253.     move.l    INTUITIONBASE,a6    ; MoveWindow(Win, ##, 0);
  254.     move.l    WIN,a0
  255.     moveq.l    #-60-24,d0
  256.     add.w    sc_Width(a5),d0        ; a5 still contains the Win->WScreen ptr
  257.     sub.w    CURRWIDTH,d0
  258.     move.w    d0,ASC0            ; ASC0 isn't '0'
  259.     lea    WantedLoc(pc),a2
  260.     sub.w    (a2),d0
  261.     move.w    ASC0,(a2)        ; ASC0 isn't '0'
  262.     moveq.l    #0,d1
  263.     jsr    _LVOMoveWindow(a6)
  264.  
  265.     move.l    WIN,a0            ; SizeWindow(Win, ##, ##);
  266.     move.w    CURRWIDTH,d0
  267.     sub.w    WIDEST,d0
  268.     moveq.l    #1,d1
  269.     add.b    sc_BarHeight(a5),d1    ; a5 still contains the Win->WScreen ptr
  270.     lea    NewWin+6(pc),a5        ; Address of CurrWinHeight to a5
  271.     sub.w    (a5),d1
  272.     add.w    d1,(a5)
  273.     jsr    _LVOSizeWindow(a6)
  274.  
  275.     move.w    CURRWIDTH,WIDEST
  276.  
  277. EndUpdate:                ; } /* end if(CurrWidth > Widest) */
  278.     moveq.l    #50,d1
  279.     sub.w    (sp),d1            ; Get former tick / 50 division % from upper word of last stack item
  280.     addq.l    #4,sp            ; Clear last stack item (whole word!)
  281.     move.l    (sp),a6            ; Now DosBase is on top of the stack
  282.     jsr    _LVODelay(a6)
  283.  
  284.     move.l    EXECBASE,a6        ; if (!GetMsg(Win -> UserPort)) goto MainLoop
  285.     move.l    wd_UserPort(WIN),a0
  286.     jsr    _LVOGetMsg(a6)
  287.     tst.l    d0
  288.     beq    MainLoop
  289.  
  290.     move.l    d0,a1            ; ReplyMsg(WinIDCMP);
  291.     jsr    _LVOReplyMsg(a6)
  292.  
  293.     move.l    INTUITIONBASE,a6    ; CloseWindow(Win);
  294.     move.l    WIN,a0
  295.     jsr    _LVOCloseWindow(a6)
  296.  
  297. FailedOpeningWindow:
  298.     move.l    EXECBASE,a6
  299.  
  300.     lea    _LVOCloseLibrary(a6),a5    ; CloseLib(GraphicsBase);
  301.     move.l    GRAPHICSBASE,a1
  302.     jsr    (a5)
  303.  
  304.     move.l    (sp)+,a1        ; CloseLib(DosBase); (+ restore DosBase from stack)
  305.     jsr    (a5)
  306.  
  307.     move.l    INTUITIONBASE,a1    ; CloseLib(IntuitionBase);
  308.     jsr    (a5)
  309.  
  310.     move.w    (sp)+,d0        ; Restore InheritedPri from stack
  311.     move.l    (sp)+,a1        ; Restore MyTask from stack
  312.     jsr    _LVOSetTaskPri(a6)    ; SetTaskPri(MyTask, InheritedPri);
  313.  
  314.  
  315.     moveq.l #0,d0
  316.     rts
  317.  
  318.     END
  319.